
//Copyright 1997-2009 Syrinx Development, Inc.
//This file is part of the Syrinx Web Application Framework (SWAF).
// == BEGIN LICENSE ==
//
// Licensed under the terms of any of the following licenses at your
// choice:
//
//  - GNU General Public License Version 3 or later (the "GPL")
//    http://www.gnu.org/licenses/gpl.html
//
//  - GNU Lesser General Public License Version 3 or later (the "LGPL")
//    http://www.gnu.org/licenses/lgpl.html
//
//  - Mozilla Public License Version 1.1 or later (the "MPL")
//    http://www.mozilla.org/MPL/MPL-1.1.html
//
// == END LICENSE ==
using System;
using System.Collections.Generic;
using System.Text;

using Swaf.Container;

namespace Swaf.Gui
{
	public class ActiveBizProc : INameAddressSupport
	{
		protected IBusinessProcess m_bizProc;
		protected BizProcOfflineState m_offlineState;
		protected IBizProcCoordinator m_bpc;

        protected bool m_createdFromPage = false;
        public bool CreatedFromPage { get { return m_createdFromPage; } set { m_createdFromPage = value; } }
		public bool ForceShowBizObj = false;
		public BizProcOfflineState OfflineState { get { return m_offlineState; } }

		public ActiveBizProc(IBizProcCoordinator bpc, BizProcOfflineState offlineState)
		{
			m_bpc = bpc;
			m_offlineState = offlineState;
			if(bpc.HostView != null)
				bpc.HostView.BizProcCreated(this);
		}
		internal void setBizProc(IBusinessProcess bizproc)
		{
			m_bizProc = bizproc;
		}
		public IBizProcCoordinator BPC { get { return m_bpc; } }

		public IBusinessProcess BizProc
		{
			get
			{
				if (m_bizProc == null)
				{
					m_bizProc = Application.globalApp.factories["BizProcs"].createFromNickName(OfflineState.FactoryName, this) as IBusinessProcess;
					if (m_bizProc is IBusinessProcessInternal)
						((IBusinessProcessInternal)m_bizProc).initialize();
				}
				return m_bizProc;
			}
		}

		public List<IPaginationDisplay> getPagerDisplays()
		{
			List<IPaginationDisplay> disps = null;
			List<string> keys = OfflineWidgetKeys;
			WidgetOfflineState wstate = null;
			foreach (string k in keys)
				if (m_bpc.PageState.WidgetStates.TryGetValue(k, out wstate))
					foreach (string parentId in wstate.ParentBizProcIds)
						if (wstate.BizProcWidgetType == BizProcWidgetType.pager && OfflineState.Id.CompareTo(parentId) == 0)
						{
							ActiveWidget aw = m_bpc.getActiveWidget(wstate.Id);
							if (aw != null)
							{
								if (disps == null)
									disps = new List<IPaginationDisplay>();
								disps.Add(aw.Widget as IPaginationDisplay);
							}
						}
			return disps;
		}

		public List<IBizObjListDisplay> getListDisplays()
		{
			List<IBizObjListDisplay> lists = new List<IBizObjListDisplay>();
			List<string> keys = OfflineWidgetKeys;
			WidgetOfflineState wstate = null;
			foreach (string k in keys)
				if (m_bpc.PageState.WidgetStates.TryGetValue(k, out wstate))
					foreach (string parentId in wstate.ParentBizProcIds)
						if (wstate.BizProcWidgetType == BizProcWidgetType.list && OfflineState.Id.CompareTo(parentId) == 0)
						{
							ActiveWidget aw = m_bpc.getActiveWidget(wstate.Id);
							if(aw != null)
								lists.Add(aw.Widget as IBizObjListDisplay);
						}
			return lists;
		}

		public List<IBizObjDisplay> getDetailsDisplays()
		{
			List<IBizObjDisplay> displays = new List<IBizObjDisplay>();
			List<string> keys = OfflineWidgetKeys;
			WidgetOfflineState wstate = null;
			foreach(string k in keys)
				if(m_bpc.PageState.WidgetStates.TryGetValue(k, out wstate))
					foreach (string parentId in wstate.ParentBizProcIds)
						if (wstate.BizProcWidgetType == BizProcWidgetType.disp && OfflineState.Id.CompareTo(parentId) == 0)
						{
							ActiveWidget aw = m_bpc.getActiveWidget(wstate.Id);
							if (aw != null)
								displays.Add(aw.Widget as IBizObjDisplay);
						}
			return displays;
		}

		public List<IActionTrigger> getActionTriggers()
		{
			List<IActionTrigger> trigs = new List<IActionTrigger>();
			foreach (WidgetOfflineState wstate in m_bpc.PageState.WidgetStates.Values)
				if (wstate.BizProcWidgetType == BizProcWidgetType.button && wstate.ParentBizProcIds.Contains(OfflineState.Id))
				{
					ActiveWidget aw = m_bpc.getActiveWidget(wstate.Id);
					if (aw != null)
						trigs.Add(aw.Widget as IActionTrigger);
				}
			return trigs;
		}

		public List<object> getChildControls(BizProcWidgetType t)
		{
			List<object> ctrls = new List<object>();
			foreach (WidgetOfflineState wstate in m_bpc.PageState.WidgetStates.Values)
				if (wstate.BizProcWidgetType == t && wstate.ParentBizProcIds.Contains(OfflineState.Id))
				{
					ActiveWidget aw = m_bpc.getActiveWidget(wstate.Id);
					if (aw != null)
						ctrls.Add(aw.Widget);
				}
			return ctrls;
		}

		public List<string> OfflineWidgetKeys
		{
			get
			{
				List<string> w = new List<string>(m_bpc.PageState.WidgetStates.Count);
				foreach (string k in m_bpc.PageState.WidgetStates.Keys)
					w.Add(k);
				return w;
			}
		}

		public List<IBizObjDisplay> getFilterSortDisplays()
		{
			return null;
		}
		public ActiveBizProc getParentBizProc(string name)
		{
			ActiveBizProc parent = null;
			List<ParentBizProcInfo> parentInfo = null;
			if (OfflineState.ParentBizProcs.TryGetValue(name, out parentInfo))
				parent = BPC.getActiveBizProc(parentInfo[0].ParentId);
			return parent;
		}

		#region INameAddressSupport Members

		public object get(string name)
		{
			return get(name, true);
		}

		public object get(string name, object oneArg)
		{
			try
			{
				bool useBizProcCacheIfNeeded = true;
				if (oneArg is bool)
					useBizProcCacheIfNeeded = (bool)oneArg;

				OfflineState.State.put("itsMe", true);
				if (name.CompareTo("_bizProcId") == 0)
					return OfflineState.Id;
				//First, get value directly from bizproc state.
				object val = OfflineState.State.get(name);

				//If the value is not it state, check to see if a parent bizproc is assigned to provide it
				if (val == null)
				{
					string id = this.BizProc.Id;
					List<ParentBizProcInfo> parentInfo = null;
					if (OfflineState.ParentBizProcs.TryGetValue(name, out parentInfo))
					{
						if (useBizProcCacheIfNeeded && parentInfo[0].UseCache && parentInfo[0].ParentSelectedBizObjFieldValueCache != null)
							val = parentInfo[0].ParentSelectedBizObjFieldValueCache;
						else
						{
							ActiveBizProc parent = m_bpc.getActiveBizProc(parentInfo[0].ParentId);
							if (parent != null && parent.BizProc.CurrentBizObj != null)
							{
								if (Cmn.IsEmpty(parentInfo[0].ParentSelectedBizObjFieldName))
									val = parent.BizProc.CurrentBizObj;
								else if (parentInfo[0].ParentSelectedBizObjFieldName.CompareTo("_list") == 0)
									val = parent.BizProc.SourceBizObjs;
								else
									val = parent.BizProc.CurrentBizObj.get(parentInfo[0].ParentSelectedBizObjFieldName);
								parentInfo[0].ParentSelectedBizObjFieldValueCache = val;
							}
						}
					}
				}

				//Finally, ask the hosting environment for the value via the BizProcCoordinator.
				if (val == null)
				{
					string hostName = name;
					if (name.IndexOf('.') != -1)
						hostName = hostName.Replace(".", "");
					val = m_bpc.getDataValueFromHostEnvironment(hostName, this);
					if (val != null)
						OfflineState.State.put(name, val);
				}

				return val;
			}
			finally
			{
				OfflineState.State.put("itsMe", null);
			}
		}

		public object get(string name, params object[] p)
		{
			return get(name, true);
		}

		public void put(string name, object newValue)
		{
			foreach(List<ParentBizProcInfo> pi in OfflineState.ParentBizProcs.Values)
				if (string.Compare(pi[0].DataId, name) == 0)
				{
					pi[0].ParentSelectedBizObjFieldValueCache = newValue;
					return;
				}
			OfflineState.State.put(name, newValue);	
		}

		public void put(string name, object newValue, object extraInfo)
		{
			foreach (List<ParentBizProcInfo> pi in OfflineState.ParentBizProcs.Values)
				if (string.Compare(pi[0].DataId, name) == 0)
				{
					pi[0].ParentSelectedBizObjFieldValueCache = newValue;
					return;
				}
			OfflineState.State.put(name, newValue, extraInfo);
		}

		public bool isGetOnly
		{
			get { return false; }
		}

		public XmlSerializationSupport SerializationSupport
		{
			get { return XmlSerializationSupport.None; }
		}

		public string Xml
		{
			get { throw new Exception("The method or operation is not implemented."); }
		}

		public string getXml(string options)
		{
			throw new Exception("The method or operation is not implemented.");
		}

		public bool containsField(string nameAddress)
		{
			bool hasIt = OfflineState.State.containsField(nameAddress);
			if (!hasIt && get(nameAddress) != null)
				hasIt = true;
			return hasIt;
		}

		#endregion

		#region IEnumerable Members

		public System.Collections.IEnumerator GetEnumerator()
		{
			return OfflineState.State.GetEnumerator();
		}

		#endregion
	}
}
